#include <iostream>

#include "../../loadBalance/code/RoundRobin.hpp"
#include "../../loadBalance/code/RandomSelect.hpp"
#include "../../loadBalance/code/WeightedRandom.hpp"
#include "../../loadBalance/code/HashSelect.hpp"
#include "../../loadBalance/code/ConsistentHash.hpp"

void testRoundRobin()
{
    std::cout << "=== Testing RoundRobin ===" << std::endl;

    // 初始化
    std::vector<std::string> nodes{
        "Server1:8080",
        "Server2:8081",
        "Server3:8082"};
    LoadBalance::RoundRobin<std::string> rr(nodes);

    // 获取
    for (int i = 0; i < 5; ++i)
    {
        std::string nextNode = rr.getNext();
        std::cout << "Request " << i + 1 << " : " << nextNode << std::endl;
    }
    std::cout << std::endl;
}

void testRandomSelect()
{
    std::cout << "=== Testing RandomSelect ===" << std::endl;

    // 初始化
    std::vector<std::string> nodes{
        "Server1:8080",
        "Server2:8081",
        "Server3:8082"};
    LoadBalance::RandomSelect<std::string> rs(nodes);

    // 获取
    for (int i = 0; i < 5; ++i)
    {
        std::string nextNode = rs.getNext();
        std::cout << "Request " << i + 1 << " : " << nextNode << std::endl;
    }
    std::cout << std::endl;
}

void testWeightedRandom()
{
    std::cout << "=== Testing WeightedRandom ===" << std::endl;

    // 初始化
    std::vector<std::pair<std::string, int>> nodes = {
        {"Server1:8080", 1},
        {"Server2:8081", 2},
        {"Server3:8082", 3}};
    LoadBalance::WeightedRandom<std::string> wr(nodes);

    // 获取
    for (int i = 0; i < 5; ++i)
    {
        std::string nextNode = wr.getNext();
        std::cout << "Request " << i + 1 << " : " << nextNode << std::endl;
    }
    std::cout << std::endl;
}

void testHashSelect()
{
    std::cout << "=== Testing HashSelect ===" << std::endl;

    // 初始化
    std::vector<std::string> nodes = {
        "Server1:8080",
        "Server2:8081",
        "Server3:8082"};
    LoadBalance::HashSelect<std::string> hs(nodes);

    // 获取
    std::vector<std::string> keys = {
        "key1",
        "key2",
        "key3",
        "key1",
        "key3"};
    for (const auto &key : keys)
    {
        std::string node = hs.getNode(key);
        std::cout << "Key: " << key << " is handled by node: " << node << std::endl;
    }
    std::cout << std::endl;
}

void testConsistentHash()
{
    std::cout << "=== Testing ConsistentHash ===" << std::endl;

    // 添加
    LoadBalance::ConsistentHash<std::string> ch(3);
    std::vector<std::string> nodes = {
        "Server1:8080",
        "Server2:8081",
        "Server3:8082"};
    for (const auto &node : nodes)
    {
        ch.addNode(node);
    }

    // 获取
    std::vector<std::string> keys = {
        "key1",
        "key2",
        "key3",
        "key4",
        "key5"};
    for (const auto &key : keys)
    {
        std::string node = ch.getNode(key);
        std::cout << "Key: " << key << " is handled by node: " << node << std::endl;
    }
    std::cout << std::endl;

    // 删除
    std::cout << "Removing Server2:8081" << std::endl;
    ch.delNode("Server2:8081");

    // 获取
    for (const auto &key : keys)
    {
        std::string node = ch.getNode(key);
        std::cout << "Key: " << key << " is handled by node: " << node << std::endl;
    }
    std::cout << std::endl;
}

int main()
{
    testRoundRobin();
    testRandomSelect();
    testWeightedRandom();
    testHashSelect();
    testConsistentHash();

    return 0;
}